home *** CD-ROM | disk | FTP | other *** search
- RCS_ID_C="$Id: sana2config.c,v 3.2 1994/02/03 19:10:09 ppessi Exp $";
- /*
- * Copyright (c) 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
- * Helsinki University of Technology, Finland.
- * All rights reserved.
- *
- * sana2config.c - Configuration parameters for SANA-II network interfaces
- *
- * HISTORY
- * $Log: sana2config.c,v $
- * Revision 3.2 1994/02/03 19:10:09 ppessi
- * Changed the interface database format
- *
- * Revision 3.1 1994/02/03 03:50:38 ppessi
- * Initially tested version
- *
- */
-
- #include <conf.h>
-
- #include <sys/param.h>
- #include <sys/socket.h>
- #include <sys/socketvar.h>
- #include <net/if.h>
- #include <net/if_types.h>
- #include <assert.h>
-
- #if NS
- #error NS is not supported
- #endif
-
- #include <kern/amiga_includes.h>
- #if __SASC
- #include <proto/dos.h>
- #elif __GNUC__
- #include <inline/dos.h>
- #else
- #error Your compiler is not supported in this release.
- #endif
-
- #include <netinet/in.h>
- #include <devices/sana2.h>
- #include <utility/tagitem.h>
- #include <net/sana2tags.h>
- #include <net/sana2config.h>
- #include <net/if_arp.h>
- #include <net/if_sana.h>
-
- static const char template[] = SSC_TEMPLATE;
-
- #define CONFIGLINELEN 1024
-
- /*
- * Parse the configuration
- */
- static struct ssconfig *
- ssconfig_parse(struct CSource argfile[])
- {
- struct ssconfig *config = AllocVec(sizeof(*config), MEMF_CLEAR|MEMF_PUBLIC);
- /*
- * Initialize the RDArgs structure for ReadArgs()
- */
- struct RDArgs *rdargs = config->rdargs;
-
- if (config != NULL) {
- rdargs->RDA_Source = *argfile;
- rdargs->RDA_DAList = NULL;
- rdargs->RDA_Buffer = NULL;
- rdargs->RDA_BufSiz = 0;
- rdargs->RDA_ExtHelp = NULL;
- rdargs->RDA_Flags = RDAF_NOPROMPT;
-
- if (ReadArgs(template, (LONG *)config->args, rdargs)) {
- config->flags |= SSCF_RDARGS;
- return config;
- } else {
- FreeVec(config);
- }
- }
- return NULL;
- }
-
- /*
- * Free the configuration
- */
- void
- ssconfig_free(struct ssconfig config[])
- {
- if (config->flags & SSCF_RDARGS)
- FreeArgs(config->rdargs);
- FreeVec(config);
- }
-
- static int
- getconfs(BPTR iffh, UBYTE *buf)
- {
- LONG i, quoted = 0, escaped = 0;
-
- if (FGets(iffh, buf, CONFIGLINELEN - 1)) {
- for (i = 0; buf[i]; i++) {
- UBYTE c = buf[i];
- if (c == '\n') {
- if (quoted) {
- return ERROR_UNMATCHED_QUOTES;
- }
- if (i > 0 && buf[i - 1] == '+') {
- i--;
- if (i < CONFIGLINELEN - 2) {
- if (FGets(iffh, buf + i, CONFIGLINELEN - 1 - i))
- continue;
- return IoErr();
- }
- return ERROR_LINE_TOO_LONG;
- }
- return 0;
- } else if (quoted) {
- if (escaped) {
- escaped = 0;
- } else if (c == '*') {
- escaped = 1;
- continue;
- } else if (c == '"') {
- quoted = 0;
- }
- } else if (c == ';' || c == '#') {
- buf[i++] = '\n';
- buf[i] = '\0';
- return 0;
- } else if (escaped) {
- escaped = 0;
- } else if (c == '*') {
- escaped = 1;
- } else if (c == '"') {
- quoted = 1;
- }
- }
- return ERROR_LINE_TOO_LONG;
- }
-
- buf[0] = '\0';
- return IoErr();
- }
-
- /*
- * Read configuration file
- */
- struct ssconfig *
- ssconfig_make(int how, char *unitname, long unit)
- {
- LONG ioerr = 0;
- BPTR iffh;
- UBYTE *buf;
- struct ssconfig *ssc = NULL, *ssc_generic = NULL;
- char devname[IFNAMSIZ];
- char *cp;
-
- if (how == SSC_ALIAS) {
- /* Copy the interface name */
- cp = strncpy(devname, unitname, IFNAMSIZ);
- devname[IFNAMSIZ-1] = '\0';
-
- for (; *cp; cp++)
- if (*cp >= '0' && *cp <= '9')
- break;
- *cp = '\0';
- }
- #ifdef COMPAT_AMITCP2
- else if (how == SSC_COMPAT) {
- }
- #endif
- else {
- return NULL;
- }
-
- buf = AllocVec(CONFIGLINELEN, MEMF_PUBLIC);
- iffh = Open(_PATH_SANA2CONFIG, MODE_READWRITE);
- if (iffh && buf) {
- BPTR oldinfh = SelectInput(iffh);
- struct CSource arg[1];
-
- /* There is bug in FGets -- the last char is not necessary 0 */
- buf[CONFIGLINELEN - 1] = '\0';
-
- while ((ioerr = getconfs(iffh, buf)) == 0) {
- struct ssconfig *s;
- if (buf[0] == '\n')
- continue;
- if (buf[0] == '\0')
- break;
-
- arg->CS_Buffer = buf;
- arg->CS_Length = strlen(buf);
- arg->CS_CurChr = 0;
- if (s = ssconfig_parse(arg)) {
- if (how == SSC_ALIAS) {
- s->unit = unit;
- if (strcmp(s->args->a_name, unitname) == 0) {
- ssc = s;
- break;
- } else if (ssc_generic == NULL &&
- strcmp(s->args->a_name, devname) == 0) {
- ssc_generic = s;
- continue;
- }
- }
- #ifdef COMPAT_AMITCP2
- else if (how == SSC_COMPAT) {
- /*
- * Try to find interface with matching exec device and unit
- */
- if (strcmp(FilePart(s->args->a_dev), FilePart(unitname)) == 0 &&
- (s->args->a_unit == NULL || *s->args->a_unit == unit)) {
- /* Copy the devname */
- cp = strncpy(devname, s->args->a_name, IFNAMSIZ);
- devname[IFNAMSIZ-1] = '\0';
-
- for (; *cp; cp++)
- if (*cp >= '0' && *cp <= '9')
- break;
-
- if (*cp) {
- /* an interface with unit number, eg. "slip0" */
- int ifunit = *cp - '0';
- *cp++ = '\0';
-
- while (*cp >= '0' && *cp <= '9')
- ifunit = ifunit * 10 + *cp++ - '0';
-
- if (s->args->a_unit == NULL && ifunit != unit) {
- continue;
- }
- s->unit = ifunit;
- } else {
- /* an interface sans unit number, eg. "slip" */
- s->unit = unit - (s->args->a_unit ? *s->args->a_unit : 0);
- }
- *cp = '\0';
- ssc = s;
- break;
- }
- }
- #endif
- ssconfig_free(s);
- continue;
- }
- break;
- }
- SelectInput(oldinfh);
- } else {
- if (buf)
- ioerr = IoErr();
- else
- ioerr = ERROR_NO_FREE_STORE;
- }
-
- if (iffh) Close(iffh);
- if (buf) FreeVec(buf);
-
- if (ioerr) {
- if (ssc)
- ssconfig_free(ssc);
- if (ssc_generic)
- ssconfig_free(ssc_generic);
- ssc_generic = ssc = NULL;
- }
-
- if (ssc == NULL) {
- ssc = ssc_generic;
- } else {
- if (ssc && ssc_generic)
- ssconfig_free(ssc_generic);
- ssc_generic = NULL;
- }
-
- if (ssc) {
- if (ssc->args->a_unit) {
- if (ssc_generic)
- *ssc->args->a_unit += unit;
- } else {
- ssc->args->a_unit = &ssc->unit;
- }
-
- strcpy(ssc->name, devname);
- }
-
- return ssc;
- }
-
- /*
- * Default configuration as per hardware type
- */
- static const struct wire_defaults {
- LONG wd_wiretype;
- LONG wd_iptype; /* IP packet type */
- WORD wd_ipno; /* SANA-II requests reserved for receiving */
- WORD wd_writeno; /* SANA-II requests reserved for sending */
- LONG wd_arptype; /* ARP packet type */
- WORD wd_arpno; /* SANA-II requests reserved for ARP */
- WORD wd_arphdr; /* ARP version */
- WORD wd_ifflags; /* Interface flags */
- BYTE wd_pad[2];
- } wire_defaults[] = {
- {
- S2WireType_Ethernet,
- ETHERTYPE_IP, 16, 16,
- ETHERTYPE_ARP, 4, 1,
- IFF_NOTRAILERS|IFF_BROADCAST|IFF_SIMPLEX,
- },
- {
- S2WireType_Arcnet,
- ARCOTYPE_IP, 16, 16,
- ARCOTYPE_ARP, 4, 7,
- IFF_NOTRAILERS|IFF_BROADCAST|IFF_SIMPLEX,
- },
- {
- S2WireType_SLIP,
- SLIPTYPE_IP, 8, 8,
- 0, 0, 0,
- IFF_NOTRAILERS|IFF_POINTOPOINT|IFF_NOARP,
- },
- {
- S2WireType_CSLIP,
- SLIPTYPE_IP, 8, 8,
- 0, 0, 0,
- IFF_NOTRAILERS|IFF_POINTOPOINT|IFF_NOARP,
- },
- {
- S2WireType_PPP,
- PPPTYPE_IP, 8, 8,
- 0, 0, 0,
- IFF_NOTRAILERS|IFF_POINTOPOINT|IFF_NOARP,
- },
- /* Use ethernet as default */
- {
- 0,
- ETHERTYPE_IP, 16, 16,
- ETHERTYPE_ARP, 4, 1,
- IFF_NOTRAILERS|IFF_BROADCAST|IFF_SIMPLEX,
- },
- };
-
- /*
- * Initialize sana_softc
- */
- void
- ssconfig(struct sana_softc *ifp, struct ssconfig *ifc)
- {
- const struct ssc_args *args = ifc->args;
- const struct wire_defaults *wd;
- LONG wt = ifp->ss_hwtype;
- LONG reqtotal = 0;
-
- assert(ifp != NULL);
- assert(ifp->ss_if.if_type == IFT_SANA);
-
- for (wd = wire_defaults; wd->wd_wiretype != 0; wd++) {
- if (wt == wd->wd_wiretype)
- break;
- }
-
- ifp->ss_ip.type = args->a_iptype ? *args->a_iptype : wd->wd_iptype;
- reqtotal += ifp->ss_ip.reqno = args->a_ipno ? *args->a_ipno : wd->wd_ipno;
-
- ifp->ss_arp.type = args->a_arptype ? *args->a_arptype : wd->wd_arptype;
- reqtotal += ifp->ss_arp.reqno = args->a_arpno ? *args->a_arpno : wd->wd_arpno;
- ifp->ss_arp.hrd = args->a_arphdr ? *args->a_arphdr : wd->wd_arphdr;
-
- reqtotal += args->a_writeno ? *args->a_writeno : wd->wd_writeno;
-
- if (reqtotal > 65535)
- reqtotal = 65535;
- ifp->ss_reqno = reqtotal;
-
- {
- UWORD ifflags = wd->wd_ifflags;
-
- if (args->a_noarp)
- ifflags |= IFF_NOARP;
- if (args->a_point2point) {
- ifflags |= IFF_POINTOPOINT;
- ifflags &= ~IFF_BROADCAST;
- }
- if (args->a_nosimplex)
- ifflags &= ~IFF_SIMPLEX;
- if (args->a_loopback)
- ifflags |= IFF_LOOPBACK;
-
- ifp->ss_if.if_flags = ifflags;
- }
-
- /* Flags for soft_sanac */
- ifp->ss_cflags = SS_CFLAGS;
-
- if (args->a_notrack)
- ifp->ss_cflags &= ~(SSF_TRACK);
-
- /* Set up name */
- ifp->ss_if.if_name = strcpy(ifp->ss_name, ifc->name);
- ifp->ss_if.if_unit = ifc->unit;
- ifp->ss_execname = strcpy((char *)(ifp + 1), ifc->args->a_dev);
- ifp->ss_execunit = *ifc->args->a_unit;
- }
-
-